package comtgl.demo.aspect;

import comtgl.demo.annotation.RateLimit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class RateLimitAspect {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Around("@annotation(comtgl.demo.annotation.RateLimit)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        // 获取方法上的限流注解
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RateLimit rateLimit = method.getAnnotation(RateLimit.class);

        // 生成限流key
        String secondKey = "rate_limit:second:" + rateLimit.key();
        String minuteKey = "rate_limit:minute:" + rateLimit.key();

        // 检查秒级限流
        long currentSecondCount = redisTemplate.opsForValue().increment(secondKey, 1);
        if (currentSecondCount == 1) {
            redisTemplate.expire(secondKey, 1, TimeUnit.SECONDS);
        }
        if (currentSecondCount > rateLimit.secondLimit()) {
            throw new RuntimeException(rateLimit.message());
        }

        // 检查分钟级限流
        long currentMinuteCount = redisTemplate.opsForValue().increment(minuteKey, 1);
        if (currentMinuteCount == 1) {
            redisTemplate.expire(minuteKey, 60, TimeUnit.SECONDS);
        }
        if (currentMinuteCount > rateLimit.minuteLimit()) {
            throw new RuntimeException(rateLimit.message());
        }

        // 放行请求
        return joinPoint.proceed();
    }
}